package com.itheima.trade.aop;

import com.itheima.model.common.dtos.AccountDto;
import com.itheima.model.common.dtos.ResponseResult;
import com.itheima.model.common.enums.AppHttpCodeEnum;
import com.itheima.model.common.feign.fallback.client.LogClient;
import com.itheima.model.common.pojos.Trade;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.time.LocalDate;

@Aspect
@Component
@Slf4j
@RequiredArgsConstructor
public class AutoLogAOP1 {

    private final LogClient logClient;

    // 指定切面
    @Pointcut("execution(* com.itheima.trade.service.AccountService.*(..)) && @annotation(com.itheima.trade.annotation.AutoLogFill)")
    public void autoLog() {
    }

    // 在方法执行之后执行
    @Around("autoLog()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Trade trade = new Trade();
        // 1.获取参数,封装Trade对象
        // 1.1.获取方法名 --> 确定操作名称
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String methodName = signature.getName();
        switch (methodName) {
            case "transfer":
                trade.setTradeType("转账");
                break;
            case "withdrawMoney":
                trade.setTradeType("取钱");
                break;
            case "saving":
                trade.setTradeType("存钱");
                break;
            default:
                 joinPoint.proceed();
        }
        // 1.2.获取参数
        Object[] args = joinPoint.getArgs();
        if (args == null || args.length == 0) {
            return joinPoint.proceed();
        }
        // 1.3.获取参数对象
        AccountDto accountDto = (AccountDto) args[0];
        trade.setAid(accountDto.getAid());
        trade.setTradeMoney(accountDto.getTransferAmount());
        trade.setTradeTime(LocalDate.now());

        StringBuilder info = new StringBuilder();
        info.append(accountDto.getCardno()).append(" ").append(trade.getTradeType()).append(" ");
        // 2.执行方法获取返回值 拼接信息
        ResponseResult result = null;
        try {
            result = (ResponseResult) joinPoint.proceed();
            if ("转账".equals(trade.getTradeType())){
                AccountDto toAccountDto = (AccountDto) args[1];
                info.append(toAccountDto.getCardno()).append(" ");
            }
            info.append(trade.getTradeMoney()).append(" 元成功");
        } catch (Exception e) {
            info.append("失败,异常信息: ").append(e.getMessage());
            log.error("操作失败: {}", e.getMessage());
            result = ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        trade.setTradeDigest(info.toString());
        // 调用log中的方法记录日志
        logClient.recordLog(trade);

        // 放行
        return result;
    }
}
